<script setup lang="ts">
// 分时折扣
import {message} from "ant-design-vue";
import {WxtBizCode, WxtUtils} from "~/contentScripts/views/wxt/lib/wxtUtils";
import WxtModal from "~/contentScripts/views/wxt/wxt-modal.vue";

const emit = defineEmits(['refresh']);
const props = defineProps({
  rows: {
    type: Array as PropType<any[]>,
    default: () => []
  },
  bizCode: {
    type: String as PropType<WxtBizCode>,
    default: WxtBizCode.关键字推广,
  },
});
const visible = ref(false);
const handle = () => {
  // return;
  if (props.rows.length === 0) {
    message.error("请选择需要批量处理的数据！");
    return;
  }
  if (!visible.value) {
    recommendTemplate.value = [];
    loadRecommendTemplates();
    calcDataSource();
    visible.value = true;
  }
}
const circleItems = [
  {
    color: '#1677ff',
    r: 22,
    g: 119,
    b: 255,
    label: '30%-100%',
    min: 30,
    max: 99,
  },
  {
    color: '#ff6a00',
    r: 255,
    g: 106,
    b: 0,
    label: '100%-200%',
    min: 100,
    max: 199,
  },
  {
    color: '#ff0000',
    r: 255,
    g: 0,
    b: 0,
    label: '200%-250%',
    min: 200,
    max: 250,
  },
]
const weeks = [
  {
    name: '周一',
  },
  {
    name: '周二',
  },
  {
    name: '周三',
  },
  {
    name: '周四',
  },
  {
    name: '周五',
  },
  {
    name: '周六',
  },
  {
    name: '周日',
  },
]
const isSelecting = ref<Boolean>(false);
const selectingElement = ref<HTMLElement | null>(null);
const startEvent = ref<any>();
const showUpdate = ref(false);
const startSelection = (event: { layerX: number; layerY: number; }) => {
  selectingRows.value = [];
  document.querySelectorAll('.week-data').forEach((td: Element) => {
    td.classList.remove('selected');
  });
  isSelecting.value = true;
  startEvent.value = event;
  if (selectingElement.value) {
    selectingElement.value.style.display = 'block';
    selectingElement.value.style.left = `${event.layerX}px`;
    selectingElement.value.style.top = `${event.layerY}px`;
    selectingElement.value.style.width = '0px';
    selectingElement.value.style.height = '0px';
  }
  document.addEventListener('mousemove', handleMouseMove);
}
const endSelection = () => {
  calcSelectingRows();
  isSelecting.value = false;
  if (selectingElement.value) {
    selectingElement.value.style.display = 'none';
  }
  document.removeEventListener('mousemove', handleMouseMove);
  if (selectingRows.value.length == 0) {
    return;
  }
  showUpdate.value = true;
}
const calcSelectingRows = () => {
  const table = document.querySelector('table');
  if (table && selectingElement.value) {
    const tds = document.querySelectorAll('.week-data');
    const selectingRect = selectingElement.value.getBoundingClientRect();
    tds.forEach((td: Element) => {
      const tdRect = td.getBoundingClientRect();
      if (tdRect.left < selectingRect.right && tdRect.right > selectingRect.left && tdRect.top < selectingRect.bottom && tdRect.bottom > selectingRect.top) {
        if (!selectingRows.value.includes(td.attributes['data-row-index'].value)) {
          selectingRows.value.push(td.attributes['data-row-index'].value);
        }
      }
    })

    return selectingRows;
  }
}
const handleMouseMove = (event: MouseEvent) => {
  nextTick(() => {
    if (isSelecting.value) {
      const mouseY = event.clientY - startEvent.value.clientY;
      const mouseX = event.clientX - startEvent.value.clientX;
      const table = document.querySelector('table');
      if (table) {
        if (selectingElement.value) {
          // 设置高度
          if (mouseY < 0) {
            selectingElement.value.style.top = `${event.layerY}px`;
            selectingElement.value.style.height = `${-mouseY}px`;
          } else {
            selectingElement.value.style.height = `${mouseY}px`;
          }
          // 设置宽度
          if (mouseX < 0) {
            selectingElement.value.style.left = `${event.layerX}px`;
            selectingElement.value.style.width = `${-mouseX}px`;
          } else {
            selectingElement.value.style.width = `${mouseX}px`;
          }
        }
        const tableRect = table.getBoundingClientRect();
        const tableTop = tableRect.top;
        const tableBottom = tableRect.bottom;
        if (mouseY >= tableTop && mouseY <= tableBottom) {
          if (selectingElement.value) {
            selectingElement.value.style.height = `${mouseY - tableTop}px`;
          }
        }
      }
    }
  })
}
// 推荐模板
const recommendTemplates = ref<any[]>([]);
const loadRecommendTemplates = () => {
  // console.log('加载')
  WxtUtils.templateGetSuggest(props.bizCode).then(res => {
    if (res.data.info.ok !== true) {
      message.error(res.data.info.message);
      return;
    }
    recommendTemplates.value = res.data.data.list.map((item: any) => {
      item.label = item.cateName;
      item.value = item.templateId;
      item.templates = item.templates.map((template: any) => {
        template.label = template.templateName;
        template.value = template.templateId;
        template.templateValue = JSON.parse(template.templateValue);
        return template;
      })
      return item;
    });
  })
}
const dataSource = ref<any>({});
const calcDataSource = () => {
  let data: any = {};
  if (choseType.value == 'curr' && props.rows[0] && typeof props.rows[0].launchPeriodList !== 'undefined') {
    props.rows[0].launchPeriodList.forEach((item: {
      dayOfWeek: number,
      timeSpanList: { discount: number, time: string }[]
    }) => {
      item.timeSpanList.forEach((timeSpan: { discount: number; time: string; }) => {
        const timeArr = timeSpan.time.split('-');
        const start = parseFloat(timeArr[0].replaceAll(':', '.').replaceAll('.00', '.00').replaceAll('.30', '.5'));
        const end = parseFloat(timeArr[1].replaceAll(':', '.').replaceAll('.00', '.00').replaceAll('.30', '.5'));
        // 半个小时为一档
        for (let i = start; i < end; i += 0.5) {
          data[`${item.dayOfWeek - 1}-${i * 2}`] = timeSpan.discount;
        }
      })
    })
  } else if (choseType.value == 'full') {
    weeks.forEach((week, index) => {
      for (let i = 0; i < 48; i += 1) {
        data[`${index}-${i}`] = 100;
      }
    })
  } else if (choseType.value == 'temp' && recommendTemplate.value.length > 1) {
    if (recommendTemplate.value.length == 0) {
      weeks.forEach((week, index) => {
        for (let i = 0; i < 48; i += 1) {
          data[`${index}-${i}`] = 100;
        }
      })
    } else {
      let template = recommendTemplates.value.find((item) => {
        return item.value == recommendTemplate.value[0];
      });
      template = template?.templates.find((item: { value: any; }) => {
        return item.value == recommendTemplate.value[1];
      });
      template.templateValue.forEach((item: {
        dayOfWeek: number,
        timeSpanList: { discount: number, time: string }[]
      }) => {
        item.timeSpanList.forEach((timeSpan: { discount: number; time: string; }) => {
          const timeArr = timeSpan.time.split('-');
          const start = parseInt(timeArr[0]);
          const end = parseInt(timeArr[1]);
          // 半个小时为一档
          for (let i = start; i < end; i += 0.5) {
            data[`${item.dayOfWeek - 1}-${i * 2}`] = timeSpan.discount;
          }
        })
      })
    }
  }
  dataSource.value = data;
}

const choseType = ref(props.rows.length == 1 ? 'curr' : 'full');
const selectingRows = ref<any[]>([]);
watch(() => props.rows, (val) => {
  if (val.length == 1) {
    choseType.value = 'curr';
  } else {
    choseType.value = 'full';
  }
})
const recommendTemplate = ref<any[]>([]);
watch(() => recommendTemplate.value, (val) => {
  if (val.length===1) {
    recommendTemplate.value = [];
  }
})
const calcRgba = (circle: { r: number; g: number; b: number; min: number, max: number }, discount: number) => {
  if (typeof circle == 'undefined') {
    return '#fff';
  }
  // 根据折扣计算出透明颜色
  let a = (discount - circle.min) / (circle.max - circle.min);
  if (a < 0.1) {
    a = 0.1;
  }
  return `rgba(${circle.r},${circle.g},${circle.b},${a})`;
}
const calcColor = (circle: { r: number; g: number; b: number; min: number, max: number }, discount: number) => {
  if (typeof circle == 'undefined') {
    return '#444';
  }
  // 根据折扣计算出透明颜色
  const a = (discount - circle.min) / (circle.max - circle.min);
  if (a > 0.5) {
    return '#fff';
  } else {
    return '#444';
  }
}
watch(() => choseType.value, (val) => {
  calcDataSource();
})
watch(() => recommendTemplate.value, (val) => {
  calcDataSource();
}, {deep: true})
watch(() => props.rows, (val) => {
  if (val.length) {
    if (val.length > 1) {
      props.rows.forEach((row: any) => {
        if (row.bidType !== 'max_amount') {
          updateType.value = 'custom';
        }
      })
    } else if (val.length == 1) {
      if (props.rows[0].bidType === 'max_amount') {
        updateType.value = 'NoDiscount';
      }
    }
  }
}, {deep: true})
const updateType = ref('custom');
const customDiscount = ref(100);
const batchUpdateDiscount = ref(0);
// reduce increase
const batchUpdateType = ref('increase');
const confirmModify = () => {
  // 批量修改指定时间段的折扣
  if (updateType.value == 'custom') {
    if (customDiscount.value < 30) {
      customDiscount.value = 30;
    }
    if (customDiscount.value > 250) {
      customDiscount.value = 250;
    }
    selectingRows.value.forEach((rowIndex) => {
      dataSource.value[rowIndex] = customDiscount.value;
    })
  } else if (updateType.value == 'batch') {
    if (batchUpdateDiscount.value < 1) {
      batchUpdateDiscount.value = 1;
    }
    if (batchUpdateDiscount.value > 250) {
      batchUpdateDiscount.value = 250;
    }
    selectingRows.value.forEach((rowIndex) => {
      if (batchUpdateType.value == 'increase') {
        dataSource.value[rowIndex] = dataSource.value[rowIndex] + batchUpdateDiscount.value;
      } else {
        dataSource.value[rowIndex] = dataSource.value[rowIndex] - batchUpdateDiscount.value;
      }
      if (dataSource.value[rowIndex] < 30) {
        dataSource.value[rowIndex] = 30;
      }
      if (dataSource.value[rowIndex] > 250) {
        dataSource.value[rowIndex] = 250;
      }
    })
  } else if (updateType.value == 'NoDiscount') {
    selectingRows.value.forEach((rowIndex) => {
      dataSource.value[rowIndex] = 100;
    })
  } else if (updateType.value == 'DoNotAdvertise') {
    selectingRows.value.forEach((rowIndex) => {
      dataSource.value[rowIndex] = 0;
    })
  }
  showUpdate.value = false;
}
const radioStyle = reactive({
  display: 'flex',
  height: '30px',
  lineHeight: '30px',
});
const update = () => {
  const campaignIds: string[] = props.rows.map((r: any) => r.campaignId);
  const launchPeriodList: { dayOfWeek: number, timeSpanList: { time: string, discount: string }[] }[] = [];
  let setDiscountStatus = false;
  weeks.forEach((week, index) => {
    const timeSpanList: { time: string, discount: string }[] = [];
    for (let i = 0; i < 48; i += 1) {
      timeSpanList.push({
        time: `${parseInt(String(i / 2))}:${i % 2 === 0 ? '00' : '30'}-${parseInt(String((i + 1) / 2))}:${(i + 1) % 2 === 0 ? '00' : '30'}`,
        discount: dataSource.value[`${index}-${i}`] || 0,
      })
      if ((dataSource.value[`${index}-${i}`] || 0) > 0) {
        setDiscountStatus = true;
      }
    }
    if (timeSpanList.length > 0) {
      // time的结束时间和下一个时间段开始时间相同并且折扣相同的合并
      const newTimeSpanList: { time: string, discount: string }[] = [];
      timeSpanList.forEach((timeSpan, index) => {
        if (index == 0) {
          newTimeSpanList.push(timeSpan);
        } else {
          const lastTimeSpan = newTimeSpanList[newTimeSpanList.length - 1];
          if (lastTimeSpan.discount == timeSpan.discount && lastTimeSpan.time.split('-')[1] == timeSpan.time.split('-')[0]) {
            lastTimeSpan.time = `${lastTimeSpan.time.split('-')[0]}-${timeSpan.time.split('-')[1]}`;
          } else {
            newTimeSpanList.push(timeSpan);
          }
        }
      })
      launchPeriodList.push({
        dayOfWeek: index + 1,
        timeSpanList: newTimeSpanList,
      })
    }
  })
  if (!setDiscountStatus) {
    message.error("请至少选择一个时段投放！");
    return;
  }
  WxtUtils.advancedBatchUpdate([
    ...campaignIds.map((campaignId: string) => ({
      campaignId,
      launchPeriodList,
    })),
  ], props.bizCode).then(res => {
    visible.value = false;
    if (res.data.info.ok !== true) {
      message.error(res.data.info.message)
      return;
    }
    message.success("设置分时折扣成功！");

    visible.value = false;
    nextTick(() => {
      emit('refresh');
    });
  }).catch(() => {
    visible.value = false;
    message.error("网络异常，设置分时折扣失败！")
  });
}
</script>

<template>
  <wxt-modal :style="{
    top: 'revert-layer',
  }" title="更改折扣" :width="450" v-model:visible="showUpdate"
  >
    <a-radio-group v-model:value="updateType" style="width: 100%;">

      <a-row type="flex" v-if="rows.length===1 && rows[0].bidType!=='max_amount'">
        <a-col flex="1">
          <a-radio :style="radioStyle" value="custom">
            自定义折扣
          </a-radio>
        </a-col>
        <a-col>
          <a-input-number v-model:value="customDiscount" :min="30" :max="250" :style="{
              width: '280px'
            }"
                          size="small"
          >
            <template #addonAfter>
              %
            </template>
          </a-input-number>
        </a-col>
      </a-row>
      <a-row v-if="rows.length>0 && rows[0].bidType!=='max_amount'">
        <a-col flex="1">
          <a-radio :style="radioStyle" value="batch">
            批量调整
          </a-radio>
        </a-col>
        <a-col>
          <a-input-number v-model:value="batchUpdateDiscount" :min="1" :max="250" :style="{
              width: '280px'
            }"
                          size="small"
          >
            <template #addonBefore>
              <a-select v-model:value="batchUpdateType">
                <a-select-option value="increase">增加</a-select-option>
                <a-select-option value="reduce">减少</a-select-option>
              </a-select>
            </template>
            <template #addonAfter>
              %
            </template>
          </a-input-number>
        </a-col>
      </a-row>
      <a-radio :style="radioStyle" value="NoDiscount">
        无折扣
      </a-radio>
      <a-radio :style="radioStyle" value="DoNotAdvertise">
        不投放
      </a-radio>
    </a-radio-group>
    <div style="color: #f5222d;font-size: 12px;padding-top: 10px;">
      自定义范围：30-250的整数，增加幅度后超过250时按250计算，减少幅度后小于30按照30计算，最大化拿量仅支持设置投放时间（投放、不投放）两种状态
    </div>
    <a-divider style="margin-top: 10px;margin-bottom: 10px;"/>
    <a-row type="flex" style="text-align: right;">
      <a-col flex="1"/>
      <a-col>
        <a-space>
          <a-button type="default" @click="showUpdate=false">取消</a-button>
          <a-button type="primary" @click="confirmModify">确定</a-button>
        </a-space>
      </a-col>
    </a-row>
  </wxt-modal>
  <div @click="handle" style="display: inline-block">
    <slot>
      <a-button size="small" type="primary" ghost>分时折扣</a-button>
    </slot>
  </div>
  <wxt-modal v-model:visible="visible" width="95%" title="分时折扣" @ok="visible=false" @cancel="visible=false">
    <template #titleRight>
      <a-space style="padding-left: 10px;font-size: 12px;color: #444;">
        <span>折扣单位:(%)</span>
        <span class="circle-item" v-for="(circle,index) in circleItems">
            <span :style="{
              backgroundColor:circle.color
            }" class="circle"
            ></span>
            <span class="content">{{ circle.label }}</span>
          </span>
        <span>可以拖拽鼠标框选投放时段</span>
      </a-space>
    </template>
    <div class="drag-container" v-if="rows.length">
      <a-row type="flex" style="padding-bottom: 10px;">
        <a-col>
          <a-space>
            <a-radio-group v-model:value="choseType">
              <a-radio value="curr" :disabled="rows.length>1">当前设置</a-radio>
              <a-radio value="full">全日制投放</a-radio>
              <a-radio value="temp" v-if="recommendTemplates.length>0">自定义时段模板</a-radio>
            </a-radio-group>
            <a-cascader
                v-if="recommendTemplates.length>0"
                :options="recommendTemplates"
                v-model:value="recommendTemplate"
                size="small"
                :placeholder="'请选择模板'"
                :field-names="{ label: 'label', value: 'value', children: 'templates' }"
                :show-search="true"
                :change-on-select="true"
                :allow-clear="false"
                :style="{
              width: '300px'
            }"

            />
          </a-space>
        </a-col>
        <a-col flex="1" style="text-align: right">
            <span style="font-size: 12px;color: #666;">
              {{ rows.length }}个计划:{{ rows.map((row, index) => row.campaignName).join(' | ') }}
            </span>
        </a-col>
      </a-row>
      <table style="min-height: 700px;" @mousedown="startSelection" @mouseup="endSelection">
        <thead>
        <tr>
          <th width="4%">星期\时间</th>
          <th v-for="number in Array.from({ length: 24 }, (value, index) => index)" width="4%" colspan="2">
            {{ number }}
          </th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(row,index) in weeks" :key="index">
          <td class="week-name">{{ row.name }}</td>
          <td class="week-data" :class="{
            'selected': selectingRows.includes(`${index}-${vIndex}`),
          }" :style="{
            backgroundColor: dataSource[`${index}-${vIndex}`] ? calcRgba(circleItems.find((item)=>item.min<=dataSource[`${index}-${vIndex}`]&&item.max>=dataSource[`${index}-${vIndex}`]),dataSource[`${index}-${vIndex}`]) : '#fff',
            color: calcColor(circleItems.find((item)=>item.min<=dataSource[`${index}-${vIndex}`]&&item.max>=dataSource[`${index}-${vIndex}`]),dataSource[`${index}-${vIndex}`]),
          }" v-for="(v,vIndex) in Array.from({ length: 48 }, (value:number, i) => i)"
              :data-row-index="`${index}-${vIndex}`"
          >
            <a-tooltip>
              <template #title>
                {{ row.name }} {{ parseInt(String(v / 2)) }}:{{ v % 2 === 0 ? '00' : '30' }}
              </template>
              {{ dataSource[`${index}-${vIndex}`] || 0 }}
            </a-tooltip>
          </td>
        </tr>
        </tbody>
      </table>
      <div class="selecting-box" ref="selectingElement"></div>
    </div>
    <a-divider style="margin-top: 10px;margin-bottom: 10px;"/>
    <a-row type="flex" style="text-align: right;">
      <a-col flex="1"/>
      <a-col>
        <a-space>
          <a-button type="default" @click="visible=false">取消</a-button>
          <a-button type="primary" @click="update">确定</a-button>
        </a-space>
      </a-col>
    </a-row>
  </wxt-modal>
</template>

<style lang="less" scoped>
.circle-item {
  .circle {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 5px;
  }

  .content {
    display: inline-block;
    font-size: 12px;
    color: #666;
  }
}

.drag-container {
  position: relative;

  .selecting-box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rbga(0, 0, 0, 0.5);
    border: 1px solid #1677ff;
    pointer-events: none;
    display: none;
  }

  table {
    border-collapse: collapse;
    width: 100%;
    border: 1px solid #eee;
    // 禁止选择
    user-select: none;

    thead {
      tr {
        background: #f5f5f5;
        padding: 5px 10px;

        th {
          border: 1px solid #eee;
          padding: 5px;
          text-align: center;
        }
      }
    }

    tbody {
      tr {
        td.week-data {
          border: 1px solid #eee;
          padding: 5px;
          text-align: center;
          font-size: 12px;
          color: #666;

          &.selected {
            background: orange !important;
            color: #fff;
          }
        }

        td.week-name {
          background: #f5f5f5;
          text-align: center;
        }
      }
    }
  }
}
</style>
